<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) 2023 https://inphp.cc All rights reserved.
// | Licensed ( https://opensource.org/licenses/MIT )
// | Author: 幺月儿(https://gitee.com/lulanyin) Email: inphp@qq.com
// +----------------------------------------------------------------------
// | 第三方平台
// +----------------------------------------------------------------------
namespace app\sso\http\api\admin;

use app\sso\model\ThirdPartyAppModel;
use app\sso\model\ThirdPartyModel;
use Inphp\Core\Db\Db;
use Inphp\Core\Modules;
use Inphp\Core\Object\Message;
use Inphp\Core\Util\File;
use Inphp\Core\Util\Str;

#[\app\admin\attributes\auth(null, true)] class thirdParty
{
    public function list(): array
    {
        $list = [];
        $dir = Modules::getModule("sso")->root."/thirdParty";
        $dirs = File::getDirs($dir);
        if (!empty($dirs)) {
            foreach ($dirs as $d) {
                $config = $d["path"]."/config.php";
                if (is_file($config)) {
                    $cfg = include $config;
                    $cfg = is_array($cfg) ? $cfg : [];
                    if (isset($cfg["name"])) {
                        $list[] = [
                            "plugin"    => $d["name"],
                            "name"      => $cfg["name"],
                            "icon"      => $cfg["icon"] ?? null,
                            "apps"      => ThirdPartyAppModel::emptyQuery()->where("plugin", $d["name"])->rows()
                        ];
                    }
                }
            }
        }
        return $list;
    }

    public function save(): Message
    {
        //名称
        $name = POST("name");
        $name = !empty($name) ? Str::trim($name) : null;
        if (empty($name)) {
            return httpMessage("缺少名称");
        }
        if (mb_strlen($name) < 2 || mb_strlen($name) > 10) {
            return httpMessage("名称字符长度请控制在2~10个字符之间");
        }

        //插件名
        $plugin = POST("plugin");
        $plugin = !empty($plugin) ? Str::trim($plugin) : null;
        if (empty($plugin)) {
            return httpMessage("缺少插件名称");
        }
        $plugin = strtolower($plugin);
        //检测
        if (!Str::isLUN($plugin)) {
            return httpMessage("插件名称格式错误");
        }

        //图标
        $icon = POST("icon");
        $icon = !empty($icon) ? trim($icon) : null;

        //状态
        $state = POST("state", 1);
        $state = $state == 1 ? 1 : 0;

        $id = POST("id");
        $id = is_numeric($id) && $id > 0 ? ceil($id) : 0;

        //检测插件名称是否冲突
        $exists = ThirdPartyModel::emptyQuery()
            ->where("plugin", $plugin)
            ->where("id", "!=", $id)
            ->first();
        if (!empty($exists)) {
            return httpMessage("插件名称重复，不可使用");
        }
        $data = [
            "name"      => $name,
            "plugin"    => $plugin,
            "icon"      => $icon,
            "state"     => $state == 0 ? 0 : 1
        ];
        //保存
        $db = ThirdPartyModel::emptyQuery();
        $method = "insert";
        if ($id > 0) {
            $db->where("id", $id);
            $method = "update";
        }
        if ($db->{$method}($data)) {
            //更新配置缓存
            @$this->cache();
            return httpMessage(0, "保存成功");
        }
        return httpMessage(4, "保存失败");
    }

    /**
     * 删除单个分组
     * @return Message
     */
    public function delete(): Message
    {
        $id = POST("id");
        $id = is_numeric($id) && $id > 0 ? ceil($id) : 0;
        if ($id <= 0) {
            return httpMessage("ID参数无效");
        }
        //查询是否存在appid
        $rows = ThirdPartyAppModel::emptyQuery()
            ->where("tpId", $id)
            ->rows();
        if ($rows > 0) {
            return httpMessage("该平台存在appid，不可删除！");
        }
        $db = ThirdPartyModel::emptyQuery()->where("id", $id);
        if ($db->delete()) {
            //更新配置缓存
            @$this->cache();
            return httpMessage(0, "已删除{$db->getAffectRows()}个数据");
        }
        return httpMessage("删除操作失败");
    }

    /**
     * APP列表
     * @return array
     */
    public function appList(): array
    {
        //查询
        $db = ThirdPartyAppModel::emptyQuery("a")
            //->join(ThirdPartyModel::tableName()." p", "a.tpId=p.id")
            ->select([
                "a.*",
                //"p.icon, p.plugin, p.name as tpName"
            ]);
        //状态
        $state = GET("state");
        $state = $state == 1 || $state == '0' ? $state : null;
        if (!is_null($state)) {
            $db->where("a.state", $state);
        }

        //平台
        $tpId = GET("tpId");
        $tpId = is_numeric($tpId) && $tpId > 0 ? ceil($tpId) : 0;
        if ($tpId > 0) {
            $db->where("a.tpId", $tpId);
        }
        //平台
        $plugin = GET("plugin");
        $plugin = !empty($plugin) && $plugin != "all" ? Str::trim($plugin) : null;
        if (!empty($plugin)) {
            $db->where("a.plugin", $plugin);
        }

        //行数
        $rows = $db->rows();
        //当前页数
        $page = GET('page', 1);
        $page = is_numeric($page) && $page > 0 ? ceil($page) : 1;
        //总页数
        $pages = 1;
        //列表数据
        $list = [];
        if ($rows > 0) {
            $total = GET("total", 30);
            $total = is_numeric($total) && $total > 2 ? $total : 30;
            $pages = ceil($rows / $total);
            $page = $page > $pages ? $pages : $page;
            $offset = $total * ($page - 1);
            $list = $db->orderBy("a.weight", "asc")->orderBy("a.id", "asc")->get($total, $offset);
        }
        //返回列表数据，包含行数、页码、总页数、数据列表
        return compact("rows", "page", "pages", "list");
    }

    public function appSave(): Message
    {
        //归属平台
        $tpId = POST("tpId");
        $tpId = is_numeric($tpId) && $tpId > 0 ? ceil($tpId) : 0;
        if ($tpId <= 0) {
            //return httpMessage("缺少平台ID");
        }
        //appid
        $appid = POST("appid");
        $appid = !empty($appid) ? trim($appid) : null;
        if (empty($appid)) {
            return httpMessage("缺少appid");
        }
        //secret
        $secret = POST("secret");
        $secret = !empty($secret) ? trim($secret) : null;
        if (empty($secret)) {
            return httpMessage("缺少APP Secret");
        }
        //名称
        $name = POST("name");
        $name = !empty($name) ? Str::trim($name) : null;
        if (empty($name)) {
            return httpMessage("缺少名称");
        }
        if (mb_strlen($name) < 2 || mb_strlen($name) > 50) {
            return httpMessage("名称字符长度请控制在2~50个字符之间");
        }
        //插件名
        $plugin = POST("plugin");
        $plugin = !empty($plugin) ? Str::trim($plugin) : null;
        if (empty($plugin)) {
            return httpMessage("缺少APPID类型");
        }
        //
        $thirdPartyList = $this->list();
        if (empty($thirdPartyList)) {
            return httpMessage("没有可用的第三方授权平台插件");
        }
        $pluginList = [];
        $icon = null;
        foreach ($thirdPartyList as $tp) {
            $pluginList[] = $tp["plugin"];
            if ($tp["plugin"] == $plugin) {
                $icon = $tp["icon"] ?? null;
            }
        }
        if (!in_array($plugin, $pluginList)) {
            return httpMessage("APPID类型无效");
        }
        //备注
        $desc = POST("desc");
        $desc = !empty($desc) ? trim($desc) : null;

        //状态
        $state = POST("state", 1);
        $state = $state == 1 ? 1 : 0;

        $weight = POST("weight", 50);
        $weight = is_numeric($weight) && $weight > 0 ? ceil($weight) : 50;
        $weight = min(100, $weight);
        $weight = max(0, $weight);

        $param = POST("param");
        $param = !empty($param) ? trim($param) : null;

        $id = POST("id");
        $id = is_numeric($id) && $id > 0 ? ceil($id) : 0;

        //平台判断
        if ($tpId > 0) {
            $tp = ThirdPartyModel::emptyQuery()->where("id", $tpId)->first();
            if (empty($tp)) {
                return httpMessage("平台ID无效");
            }
        }

        //检测插件名称是否冲突
        $exists = ThirdPartyAppModel::emptyQuery()
            ->where("tpId", $tpId)
            ->where("appid", $appid)
            ->where("id", "!=", $id)
            ->first();
        if (!empty($exists)) {
            return httpMessage("appid重复，不可使用");
        }
        $data = [
            "tpId"      => $tpId,
            "plugin"    => $plugin,
            "icon"      => $icon,
            "name"      => $name,
            "desc"      => $desc,
            "appid"     => $appid,
            "secret"    => $secret,
            "state"     => $state == 0 ? 0 : 1,
            "weight"    => $weight,
            "param"     => $param
        ];
        //
        $oldTpId = 0;
        //保存
        $db = ThirdPartyAppModel::emptyQuery();
        $method = "insert";
        if ($id > 0) {
            $db->where("id", $id);
            $method = "update";
            //查原数据
            $old = ThirdPartyAppModel::emptyQuery()
                ->where("id", $id)
                ->first();
            if (!empty($old)) {
                $oldTpId = $old["tpId"];
            }
        }
        if ($db->{$method}($data)) {
            if ($oldTpId != $tpId) {
                //收录
                @ThirdPartyModel::emptyQuery()
                    ->where("id", $tpId)->increment("apps")->update();
                //移除
                if ($oldTpId > 0) {
                    @ThirdPartyModel::emptyQuery()
                        ->where("id", $oldTpId)->decrement("apps")->update();
                }
            }
            //生成缓存
            @$this->cache();
            return httpMessage(0, "保存成功");
        }
        return httpMessage(4, "保存失败");
    }

    /**
     * 删除单个分组
     * @return Message
     */
    public function appDelete(): Message
    {
        $id = POST("id");
        $id = is_numeric($id) && $id > 0 ? ceil($id) : 0;
        if ($id <= 0) {
            return httpMessage("ID参数无效");
        }
        $row = ThirdPartyAppModel::emptyQuery()->where("id", $id)->first();
        if (empty($row)) {
            return httpMessage(0, "数据已不存在");
        }
        $db = ThirdPartyAppModel::emptyQuery()->where("id", $id);
        if ($db->delete()) {
            //回收
            @ThirdPartyModel::emptyQuery()
                ->where("id", $row["tpId"])->decrement("apps")->update();
            //更新配置缓存
            @$this->cache();
            return httpMessage(0, "已删除{$db->getAffectRows()}个数据");
        }
        return httpMessage("删除操作失败");
    }

    /**
     * 生成缓存
     * @return Message
     */
    public function cache(): Message
    {
        if (ThirdPartyAppModel::cache()) {
            return httpMessage(0, "保存成功");
        }
        return httpMessage("保存失败");
    }
}